import React, { useState, useEffect, useRef } from 'react';
import { useSelector } from 'react-redux';
import { selectApi_permission } from '../../redux/Slice/userSlice';
import api from '../../utils/api';
import {
  Cascader,
  Space,
  Table,
  Input,
  Popconfirm,
  Form,
  Typography,
  message,
  Button,
  Select,
} from 'antd';
import './index.css';

import { FileExcelOutlined, SearchOutlined } from '@ant-design/icons';
import Highlighter from 'react-highlight-words';
import axios from 'axios';
import Config from '../../Config';
import { GetCasterDepartment } from '../../utils/hooks';
const { Option } = Select;

const EditableTable = () => {
  const [form] = Form.useForm();
  const [refresh, Setrefresh] = useState(false);
  const [data, setData] = useState([]);
  const [editingKey, setEditingKey] = useState('');
  const [length, setLength] = useState(0);
  const [loading, setLoading] = useState(true);
  const [role, setRole] = useState([]);
  const { departmentList, SetdepartmentList } = GetCasterDepartment();
  const [confirmLoading, setConfirmLoading] = React.useState(false);
  const [searchText, SetSearchText] = useState('');
  const [searchedColumn, SetSearchedColumn] = useState('');
  const searchInput = useRef();
  const apiPermission = useSelector(selectApi_permission);

  const handleSearch = (selectedKeys, confirm, dataIndex) => {
    confirm();
    SetSearchText(selectedKeys[0]);
    SetSearchedColumn(dataIndex);
  };

  const handleReset = clearFilters => {
    clearFilters();
    SetSearchText('');
  };
  const getColumnSearchProps = dataIndex => ({
    filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
      <div style={{ padding: 8 }}>
        <Input
          ref={searchInput}
          placeholder={`搜索 ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
          onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
          style={{ marginBottom: 8, display: 'block' }}
        />
        <Space>
          <Button
            type="primary"
            onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
            icon={<SearchOutlined />}
            size="small"
            style={{ width: 90 }}
          >
            搜索
          </Button>
          <Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
            重置
          </Button>
          <Button
            type="link"
            size="small"
            onClick={() => {
              confirm({ closeDropdown: false });
              SetSearchText(selectedKeys[0]);
              SetSearchedColumn(dataIndex);
            }}
          >
            过滤
          </Button>
        </Space>
      </div>
    ),
    filterIcon: filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />,
    onFilter: (value, record) =>
      record[dataIndex]
        ? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
        : '',
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => searchInput.select(), 100);
      }
    },
    render: text =>
      searchedColumn === dataIndex ? (
        <Highlighter
          highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
          searchWords={[searchText]}
          autoEscape
          textToHighlight={text ? text.toString() : ''}
        />
      ) : (
        text
      ),
  });

  const StringToArray = str => {
    let arr = str.trim().split(/\s+/);
    return arr.map(val => {
      return parseInt(val);
    });
  };
  useEffect(() => {
    setLoading(true);
    const fetch = async () => {
      await axios
        .all([
          axios.get(Config.baseURL + '/user/alluser').catch(err => message.error('后台出错', 1)),
          axios.get(Config.baseURL + '/role/allrole').catch(err => message.error('后台出错', 1)),
        ])
        .then(
          axios.spread(function (user, role) {
            if (user.data.code == 1) {
              let userList = user.data.data;
              userList = userList.map((val, index) => {
                return {
                  ...val,
                  key: val.id,
                  departmentId: StringToArray(val.departmentId),
                };
              });
              console.log(userList);
              setData(userList);
            } else if (user.data.code >= 10000) message.error(user.data.message, 1);
            if (role.data.code == 1) {
              let roleList = role.data.data;
              setRole(roleList);
            } else if (role.data.code >= 10000) message.error(role.data.message, 1);
          })
        );

      setLoading(false);
    };
    fetch();
  }, [refresh]);

  const isEditing = record => record.id === editingKey;
  const EditableCell = ({
    editing,
    dataIndex,
    title,
    inputType,
    record,
    index,
    children,
    ...restProps
  }) => {
    let inputNode;
    if (inputType === 'roleid') {
      inputNode = (
        <Select>
          {role.map((Item, index) => {
            return (
              <Option key={index} value={Item.roleId}>
                {Item.roleName}
              </Option>
            );
          })}
        </Select>
      );
    } else if (inputType === 'departmentId') {
      inputNode = <Cascader changeOnSelect options={departmentList}></Cascader>;
    } else if (inputType == 'sex') {
      inputNode = (
        <Select>
          <Option key={0} value="男">
            男
          </Option>
          <Option key={1} value="女">
            女
          </Option>
        </Select>
      );
    } else {
      inputNode = <Input />;
    }

    return (
      <td {...restProps}>
        {editing ? (
          <Form.Item
            name={dataIndex}
            style={{
              margin: 0,
            }}
            rules={[
              {
                required: true,
                message: `请输入 ${title}!`,
              },
            ]}
          >
            {inputNode}
          </Form.Item>
        ) : (
          children
        )}
      </td>
    );
  };
  const edit = record => {
    form.setFieldsValue({
      ...record,
    });
    setEditingKey(record.id);
  };

  const cancel = () => {
    setEditingKey('');
  };

  const save = async key => {
    setConfirmLoading(true);
    try {
      const row = await form.validateFields();
      const temp = form.getFieldValue();
      const newData = [...data];
      const index = newData.findIndex(item => key === item.key);
      let postData = {
        id: temp.id,
        name: temp.name,
        username: temp.username,
        roleid: temp.roleid,
        sex: temp.sex,
        departmentId: '',
      };
      for (let i = 0; i < temp.departmentId.length; i++)
        postData.departmentId += temp.departmentId[i] + ' ';
      console.log(postData);
      axios
        .post(Config.baseURL + '/user/changeuser', postData)
        .then(res => {
          if (res.data.code === 1) {
            message.success('修改成功', 2);
            if (index > -1) {
              const item = newData[index];
              newData.splice(index, 1, { ...item, ...temp });
              setData(newData);
              setEditingKey('');
            } else {
              newData.push(temp);
              setData(newData);
              setEditingKey('');
            }
          } else if (res.data.code >= 10000) message.error(res.data.message + ' ' + res.data, 2);

          setConfirmLoading(false);
        })
        .catch(err => {
          message.error('服务器出错', 2);
          setConfirmLoading(false);
        });
    } catch (errInfo) {
      console.log('Validate Failed:', errInfo);
      setConfirmLoading(false);
    }
  };
  const handleDelete = key => {
    const dataSource = data;
    setData(dataSource.filter(item => item.key !== key));
    setLength(length - 1);
    message.success('删除成功!');
  };
  const roleIndex = index => {
    for (let i = 0; i < role.length; i++) {
      if (role[i].roleId == index) return i;
    }
    return -1;
  };
  const departmentIdToString = (arr, departmentList) => {
    let err = '未分配部门';
    let res = '';
    let curArray = departmentList;
    for (let i = 0; i < arr.length; i++) {
      let flag = 0;
      for (let j = 0; j < curArray.length; j++) {
        if (arr[i] == curArray[j].value) {
          res += curArray[j].label + ' ';
          if (curArray[j].children != undefined) curArray = curArray[j].children;
          flag = 1;

          break;
        }
      }
      if (flag === 0) return err;
    }
    return res;
  };
  const columns = [
    {
      title: '编号',
      dataIndex: 'id',
      width: '10%',
      editable: false,
      ...getColumnSearchProps('id'),
    },
    {
      title: '用户名',
      dataIndex: 'username',
      width: '15%',
      editable: true,
      ...getColumnSearchProps('username'),
    },
    {
      title: '姓名',
      dataIndex: 'name',
      width: '10%',
      editable: true,
      ...getColumnSearchProps('name'),
    },
    {
      title: '性别',
      dataIndex: 'sex',
      width: '10%',
      editable: true,
    },
    {
      title: '部门',
      dataIndex: 'departmentId',
      width: '15%',
      render: (_, record) => {
        let arr = record.departmentId;
        let str = departmentIdToString(arr, departmentList);
        return <>{str}</>;
      },
      editable: true,
    },
    {
      title: '角色',
      dataIndex: 'roleid',
      width: '15%',
      render: (_, record) => {
        let index = roleIndex(record.roleid);
        return <>{index > -1 ? role[index].roleName : '未分组'}</>;
      },
      editable: true,
    },
    {
      title: 'operation',
      dataIndex: 'operation',
      render: (_, record) => {
        const editable = isEditing(record);
        return editable ? (
          <span>
            <Popconfirm
              title="确定要保存吗？"
              onConfirm={() => save(record.key)}
              okButtonProps={{ loading: confirmLoading }}
              okText="是"
              cancelText="否"
            >
              <a
                style={{
                  marginRight: 8,
                }}
              >
                保存
              </a>
            </Popconfirm>
            <Popconfirm title="确定要取消吗？" onConfirm={cancel} okText="是" cancelText="否">
              <a>取消</a>
            </Popconfirm>
          </span>
        ) : (
          <span>
            <Typography.Link
              disabled={editingKey !== '' || api('user:edit', apiPermission)}
              onClick={() => edit(record)}
              style={{ marginRight: '10px' }}
            >
              编辑
            </Typography.Link>
            <Popconfirm
              title="你确定要删除吗?"
              onConfirm={() => handleDelete(record.key)}
              okText="是"
              cancelText="否"
            >
              <Typography.Link disabled={editingKey !== '' || api('user:delete', apiPermission)}>
                删除
              </Typography.Link>
            </Popconfirm>
          </span>
        );
      },
    },
  ];
  const mergedColumns = columns.map(col => {
    if (!col.editable) {
      return col;
    }
    return {
      ...col,
      onCell: record => ({
        record,
        inputType: col.dataIndex,
        dataIndex: col.dataIndex,
        title: col.title,
        editing: isEditing(record),
      }),
    };
  });

  return (
    <>
      <Form form={form} component={false}>
        <Table
          loading={loading}
          components={{
            body: {
              cell: EditableCell,
            },
          }}
          bordered
          dataSource={data}
          columns={mergedColumns}
          rowClassName="editable-row"
          pagination={{
            onChange: cancel,
          }}
        />
      </Form>
    </>
  );
};
export default EditableTable;
